package com.neusoft.databus.agent.service.impl;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.stereotype.Service;

import com.neusoft.databus.agent.bean.PoolStatusBean;
import com.neusoft.databus.agent.pool.opc.OpcPool;
import com.neusoft.databus.agent.pool.serial.SerialPool;
import com.neusoft.databus.agent.pool.snmp.SnmpPool;
import com.neusoft.databus.agent.pool.socket.SocketPool;
import com.neusoft.databus.agent.pool.socket2.Socket2Pool;
import com.neusoft.databus.agent.service.SupportService;
import com.neusoft.databus.common.pool.AbstractPool;

/**
 * @author sunchf
 * @date 2018年12月28日 下午1:09:28
 */
@Service
public class SupportServiceImpl implements SupportService {
    @Autowired
    private ConfigurableApplicationContext context;

    @SuppressWarnings({"rawtypes" })
    @Override
    public List<PoolStatusBean> realtimePoolsStatus() {

        final Map<String, AbstractPool> pools = this.context.getBeansOfType(AbstractPool.class);

        final List<PoolStatusBean> beans = pools.values().stream().map(pool -> {
            final PoolStatusBean bean = new PoolStatusBean();
            bean.setName(pool.getName());
            bean.setMaxTotal(pool.getMaxTotal());
            bean.setBorrowedCount(pool.getBorrowedCount());
            bean.setReturnedCount(pool.getReturnedCount());
            bean.setCreatedCount(pool.getCreatedCount());
            bean.setDestroyedCount(pool.getDestroyedCount());
            bean.setDestroyedByEvictorCount(pool.getDestroyedByEvictorCount());
            bean.setDestroyedByBorrowValidationCount(pool.getDestroyedByBorrowValidationCount());
            bean.setMeanBorrowWaitTimeMillis(pool.getMeanBorrowWaitTimeMillis());
            bean.setMaxBorrowWaitTimeMillis(pool.getMaxBorrowWaitTimeMillis());
            bean.setNumActive(pool.getNumActive());
            bean.setNumIdle(pool.getNumIdle());
            bean.setMaxTotalPerKey(pool.getMaxTotalPerKey());
            bean.setNumWaiters(pool.getNumWaiters());
            if (pool instanceof SocketPool) {
                bean.setNumActivePerKey(((SocketPool) pool).getNumActivePerKey());
                bean.setNumWaitersByKey(((SocketPool) pool).getNumWaitersByKey());
                //bean.setAllObjects(((SocketPool) pool).listAllObjects());
                ((SocketPool) pool).listAllObjects().entrySet().forEach(it -> {
                    bean.getAllObjects().put(it.getKey(), it.getValue().size());
                });
            } else if (pool instanceof Socket2Pool) {
                bean.setNumActivePerKey(((Socket2Pool) pool).getNumActivePerKey());
                bean.setNumWaitersByKey(((Socket2Pool) pool).getNumWaitersByKey());
                ((Socket2Pool) pool).listAllObjects().entrySet().forEach(it -> {
                    bean.getAllObjects().put(it.getKey(), it.getValue().size());
                });
            } else if (pool instanceof SerialPool) {
                bean.setNumActivePerKey(((SerialPool) pool).getNumActivePerKey());
                bean.setNumWaitersByKey(((SerialPool) pool).getNumWaitersByKey());
                ((SerialPool) pool).listAllObjects().entrySet().forEach(it -> {
                    bean.getAllObjects().put(it.getKey(), it.getValue().size());
                });
            } else if (pool instanceof SnmpPool) {
                bean.setNumActivePerKey(((SnmpPool) pool).getNumActivePerKey());
                bean.setNumWaitersByKey(((SnmpPool) pool).getNumWaitersByKey());
                ((SnmpPool) pool).listAllObjects().entrySet().forEach(it -> {
                    bean.getAllObjects().put(it.getKey(), it.getValue().size());
                });
            } else if (pool instanceof OpcPool) {
                bean.setNumActivePerKey(((OpcPool) pool).getNumActivePerKey());
                bean.setNumWaitersByKey(((OpcPool) pool).getNumWaitersByKey());
                ((OpcPool) pool).listAllObjects().entrySet().forEach(it -> {
                    bean.getAllObjects().put(it.getKey(), it.getValue().size());
                });
            }

            return bean;
        }).collect(Collectors.toList());
        return beans;
    }

}
